#ifndef SYS_H
#define SYS_H
#define VGA_START 0x00200000
#define VGA_LINE_O 0x00210000
#define VGA_COLOR 0x00220000
#define VGA_SCREEN_LINE 30
#define VGA_MAXLINE 64
#define VGA_MOUSE 0x00230000
#define LINE_MASK 0x003f
#define VGA_MAXCOL 70
#define KEY_START 0x00300000
#define KEY_TAIL 0x00300010
#define NULL ((void *)0)
#define true (1)
#define false (0)
#define TIME_HEAD 0x00400000
#define KEY_CAPS 0x00300012
#define KEY_SHIFT 0x00300011

#define COLOR_DEFAULT 0x7

typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned uint32_t;
typedef unsigned long long uint64_t;
typedef uint64_t size_t;
typedef char bool;

typedef struct KEY {
  int magic;
  int c;
} KEY;

typedef struct TIME {
  uint16_t ms;
  uint16_t s;
  uint32_t min;
  uint32_t hr;
  uint32_t day;
  uint64_t val;
} TIME;

typedef union color_selector {
  struct {
    uint8_t fcolor : 3;
    uint8_t bcolor : 3;
    uint8_t reserved : 2;
  };
  uint8_t val;
} color_selector;

extern char cap_ascii[128];
extern char cap_sig_ascii[128];
extern char normal_ascii[128];
extern char sig_ascii[128];
extern char *vga_start;
extern char vga_line;
extern char *base_line;
extern int  *vga_mouse; 
extern int vga_ch;
extern unsigned char *key_buf;
extern volatile char *key_tail;
extern volatile char *key_caps;
extern volatile char *key_shift;
extern volatile char head;
extern unsigned long long *time_head;
extern uint8_t *color_bucket;
extern color_selector cur_color;
extern color_selector user_color;
extern bool mouse_invisible;
extern char unknown[];

unsigned int __umodsi3(unsigned int a, unsigned int b);
unsigned int __udivsi3(unsigned int a, unsigned int b);
unsigned int __mulsi3(unsigned int a, unsigned int b);

#define mul(a, b) (__mulsi3((a), (b)))
#define mod(a, b) (__umodsi3((a), (b)))
#define div(a, b) (__udivsi3((a), (b)))

void putstr(char *str, int color);
void gets(char *welcome1, char *welcome2, char *dest);
void putch(char ch, int color);
KEY getch(void);
int getr(void);
void vga_incre();
void incre_head(void);
void vga_init(void);
void clear_line(int lineno);
int atoi(char *a, int base);
char *itoa(int i, char *a, int base);
int fib(int n);
KEY transform(int u);
void puts(char *, int);
// int strcmp(char *a, char *b);
// unsigned strlen(char *s);
// int strStr(char *haystack, char *needle);
TIME time();
void set_color(uint32_t addr, color_selector color);
#endif